/**
 * Created by zhaomi on 16/4/25.
 */
var WebSocketServer=require('ws').Server
var client=require('./stu_redis').client()
var teacher=require('../service/teacher')
var classes=require('../service/classes')
var topic_dao=require('../dao/topic_dao')
var answer_dao=require('../dao/answer_dao')
var lesson_dao=require('../dao/lesson_dao')
var course_table_dao=require('../dao/course_table_dao')
// var s=require('serialijse')
var serialize=require('node-serialize')
var conn=new Map()
var socket_user=new Map()
var course_students="course_students"
var lessons="lessons"
var miss_students="miss_students"
module.exports={
  start:function() {

    var wss = new WebSocketServer({port: 8888})
    wss.on('connection', function (ws) {
      // client.multi([["sismember","jx","1"]]).exec(function (err,reply) {
      //   console.log(reply[0])
      // })
      // console.log(ws)
      var test1 = serialize.serialize({a: "1"})
      // console.log(ws)
      // console.log(test1)
      // try{
      // var test2=serialize.serialize(ws)
      // console.log(serialize.unserialize(test2)==ws)
      // }catch (e){
      //   console.log("error: "+e.stack)
      // }
      // console.log("open")
      ws.send(JSON.stringify({events: 'connect', msg: '连接成功'}))
      // users.push(ws)
      // console.log(ws)
      try{
      ws.on("message", function (data) {
        try {
          var last_heath = new Date()
          /**
           * 登录
           */
          var result = JSON.parse(data)
          if (result.events == 'login') {
            console.log(result.msg.username + " login")
            if (conn.has(result.msg.username)) {
              conn.get(result.msg.username).send(JSON.stringify({events: 'logout', msg: '该账号在另外一个设备登录'}))
              socket_user.delete(conn.get(result.msg.username))
              conn.get(result.msg.username).close(1000, '该账号在另外一个设备登录')
              conn.delete(result.msg.username)
              // ws.send()
            }
            conn.set(result.msg.username, ws)
            // console.log('set ' + result.msg.username)
            socket_user.set(ws, result.msg.username)
            // setInterval(function(){
            //   ws.send(JSON.stringify({events:'server_hert'}))
            //   var lastReplyTime
            // },300000)
            // console.log(result.events)
            // var keys=conn.keys()
            // console.log(keys.length)
            // console.dir(keys)
          }
          /**
           * 上课
           */
          if (result.events == 'begin_class') {
            var begin_time=new Date()
            var classId = result.data.classId
            var tea = result.data.teacher
            var courseTableId=result.data.courseTableId
            console.log("courseTableId: "+courseTableId)
            if (classId && tea && courseTableId) {
              client.multi([
                  ["hexists",lessons,courseTableId]
              ]).exec(function (err,replies) {
                if(err){
                  if(ws){
                    ws.send(JSON.stringify({code:500,msg:'服务器内部错误'}))
                  }
                }else if(replies[0]!=0){
                  if(ws){
                    client.multi([
                        ["hget",lessons,courseTableId]
                    ]).exec(function (err,replies) {
                      if(err){
                        if(ws){
                          ws.send(JSON.stringify({code:500,msg:'服务器内部错误'}))
                        }
                      }else{
                        ws.send(JSON.stringify({events: 'begin_class', msg: '上课开始' ,data:{lessonId:replies[0]}}))
                      }
                    })

                  }
                }else {
                  course_table_dao.is_end_class(courseTableId,function (results) {
                    if(results&&results[0].is_end){
                      if(ws){
                        ws.send(JSON.stringify({events:'class_is_end',msg:"该课程已经结束"}))
                        console.log("该课程已经结束")
                      }
                    }else {
                      lesson_dao.insertLesson(courseTableId,begin_time,function (lesson) {
                        classes.getStudentsByClassId(classId, function (students) {
                          client.multi([
                            ["hset",course_students,tea,JSON.stringify(students)],
                            ["hset",lessons,courseTableId,lesson.insertId]
                          ]).exec(function (err,replies) {
                            console.log("hset tea students")
                          })
                          setTimeout(function () {
                            client.multi([
                              ["hdel",course_students,tea],
                              ["hdel",lessons,courseTableId]
                            ]).exec(function (err,replies) {
                              console.log("hdel tea students")
                            })
                            course_table_dao.end_class(courseTableId,function (results) {
                              console.log(results)
                              broadcast(users,JSON.stringify({events:"end_class",msg:'下课了',data:{lessonId:lessonId}}))
                            })
                          },3300000)
                          setTimeout(function () {
                            if (ws) {
                              if (socket_user.has(ws)) {
                                try {
                                  ws.send(JSON.stringify({events: 'class_is_end', msg: '下课时间到了,请下课,如不操作,10分钟后服务器将强制下课'}))
                                } catch (e) {
                                  console.log("error: " + e.stack)
                                }
                                // console.log('下课了')
                              }
                            }
                          }, 2700000)
                          ws.send(JSON.stringify({events: 'begin_class', msg: '上课开始' ,data:{lessonId:lesson.insertId}}))
                        })
                      })
                    }
                  })

                }
              })


            } else {
              if (ws) {
                ws.send(JSON.stringify({code: 400, msg: "参数错误"}))
              }
            }
          }
          /**
           * 点名
           */
          if (result.events == 'call_name') {
            var call_name_time=new Date()
            var tea = result.data.teacher
            var classId = result.data.classId
            var lessonId=result.data.lessonId
            var emoji=result.data.emoji
            if (tea && classId && lessonId && emoji) {
              lesson_dao.updateLesson(lessonId,call_name_time,function (lesson) {
                var students
                client.hget(course_students, tea, function (err, reply) {
                  if (err) {
                    ws.send(JSON.stringify({code: 500, msg: 'redis错误'}))
                    console.log(err)
                  } else if (reply) {
                    students = JSON.parse(reply)
                    // console.log(students)
                    var users = new Array()
                    for (var i = 0; i < students.length; i++) {
                      users.push(students[i].username
                      )
                    }
                    // console.log(users)
                    broadcast(users, JSON.stringify({events: 'call_name', data: {teacher: result.data.teacher,emoji:emoji}}))
                    ws.send(JSON.stringify({events: 'call_name', msg: "开始点名",data:{callNameTime:call_name_time,emoji:emoji}}))
                    client.hset(miss_students, classId, reply,function () {
                      client.expire(classId, 120)
                    })

                  } else {
                    ws.send(JSON.stringify({code: 400, msg: '当前课程已经结束'}))
                    // console.log('不能call_name了')
                  }
                })
              })
            } else {
              if (ws) {
                ws.send(JSON.stringify({code: 400, msg: '参数不正确'}))
              }
            }
          }
          /**
           * 点个人名
           */
          if(result.events=='call_one'){
            var stu=result.data.student
            // console.log("call_one"+stu)
            // var classId = result.data.classId
            // var lessonId=result.data.lessonId
            var tea=result.data.teacher
            var emoji=result.data.emoji
            // console.log()
            if(stu&&tea&&emoji){
              var stu_ws=conn.get(stu)
              if(stu_ws){
                stu_ws.send(JSON.stringify({events:"call_name",data:{teacher:tea,emoji:emoji}}))
                if(ws){
                  ws.send(JSON.stringify({events:"call_one",msg:"点名成功"}))
                }
              }else{
                if(ws){
                  ws.send(JSON.stringify({events:"call_one",msg:"学生不在线",data:{student:stu}}))
                }
              }}
            else {
              if(ws){
                ws.send(JSON.stringify({code:400,msg:"参数不正确"}))
              }
            }
          }
          /**
           * 学生确认点名信息,即签到
           */
          if (result.events == 'check_in') {
            // console.log(result)

            // console.log(result.data)
            // console.log(result.data.teacher)
            // var keys=conn.keys()
            // for(var i in keys){
            //   console.log("Key i:"+keys[i])
            // }
            var tea = conn.get(result.data.teacher)
            var stu = result.data.student
            var classId = result.data.classId
            // var lessonId = result.data.lesso
            // nId
            // console.log(result.data)
            if (tea && stu && classId) {
              // console.log(tea)
              // console.log(stu)
              if (tea != undefined) {
                tea.send(JSON.stringify({events: 'check_in', student: stu}))
                ws.send(JSON.stringify({events: 'check_in', msg: '报到成功'}))
                console.log("报到成功")
              }
              client.hget(miss_students, classId, function (err, reply) {
                if (err) {
                  ws.send(JSON.stringify({code: 500, msg: 'redis错误'}))
                  console.log(err)
                } else {
                  var stus = JSON.parse(reply)
                  if (stu != undefined && stu != null) {
                    for (i in stus) {
                      if (stus[i].username == stu) {
                        stus.splice(i, 1)
                      }
                    }
                  }
                  client.hset(miss_students, classId, JSON.stringify(stus))
                  client.expire(classId, 120)
                }
              })
            } else {
              if (ws) {
                ws.send(JSON.stringify({code: 400, msg: '参数不正确'}))
              }
            }

          }
          /**
           * 接收客户端心跳包返回信息
           */
          if (result.events == 'heart') {
            ws.send(JSON.stringify({events: 'heart', msg: '服务器收到'}))
          }
          /**
           * 教师发送题目给学生
           */
          if (result.events == 'send_topic') {
            // console.log('send_topic')
            var send_topic_time=new Date()
            var tea = result.data.teacher
            var emoji=result.data.emoji
            var lessonId=result.data.lessonId
            if (tea && emoji && lessonId) {
              // console.log("teacher:"+tea)
              client.hget(course_students, tea, function (err, reply) {
                if (err) {
                  ws.send(JSON.stringify({code: 500, msg: 'redis错误'}))
                  console.log(err)
                } else if (reply) {
                  students = JSON.parse(reply)
                  var users = new Array()
                  // console.log(students)
                  for (var i = 0; i < students.length; i++) {
                    // console.log(students[i].username)
                    users.push(students[i].username)
                  }
                  result.data.send_time=new Date()
                  result.data.emoji=emoji
                  broadcast(users, JSON.stringify({events: 'send_topic', data: result.data}))
                  ws.send(JSON.stringify({events: 'send_topic', msg: "发送题目"}))
                  lesson_dao.send_topic(lessonId,result.data.topicId,tea,emoji,send_topic_time,function (sendTopic) {
                    if(sendTopic){
                      console.log('发题记录成功')
                    }
                  })
                } else {
                  console.log("课程已经结束")
                  ws.send(JSON.stringify({code: 400, msg: '当前课程已经结束'}))
                }
              })
            } else {
              if (ws) {
                ws.send(JSON.stringify({code: 400, msg: '参数错误'}))
              }
            }
          }
          if (result.events == 'answer_question') {
            var answer_time = new Date()
            var emoji=result.data.emoji
            var subject = result.data.subject
            var stu = result.data.student
            var tea = result.data.teacher
            var topicId = result.data.topicId
            var content = result.data.content
            var answer = result.data.answer
            var send_time=result.data.send_time
            var lessonId=result.data.lessonId
            console.log(result.data)
            if (subject && stu && tea && topicId && content && answer&&send_time && emoji && lessonId) {
              topic_dao.getAnswerQuestionByLessonIdAndStudent(lessonId,stu,topicId,function (answerQuestionId) {
                var is_true = false
                switch (answer) {
                  case '0':
                    answer = 'A'
                    break
                  case '1':
                    answer = 'B'
                    break
                  case '2':
                    answer = 'C'
                    break
                  case '3':
                    answer = 'D'
                    break
                }
                var answer_use_time=(answer_time.getTime()-new Date(send_time).getTime())/1000
                topic_dao.getChooseTopicById(topicId, function (topic) {
                  // console.log(topic[0].answer)
                  if (answer == topic[0].answer) {
                    is_true = true
                  }
                  console.log("length"+answerQuestionId.length)
                  // var answerQuestions=JSON.parse(answerQuestionId)
                  if(answerQuestionId.length>0){
                    // console.log("answer: "+answer)
                    topic_dao.updateAnswerQuestionByLessonIdAndStudent(is_true,answer_time,answer_use_time,emoji,answerQuestionId[0].id,answer,function (results) {
                      if(!results){
                        conn.get(tea).send({events: 'answer_question', msg: "更新失败"})
                      }else{
                        console.log("更新结果"+results)
                        var tea_ws = conn.get(tea)
                        if (tea_ws) {
                          tea_ws.send(JSON.stringify({
                            events: 'answer_question',
                            data: {
                              student: stu,
                              is_true: is_true,
                              // answerId: results.insertId,
                              content: content,
                              topicId: topicId,
                              emoji:emoji
                            }
                          }))
                        } else {
                          ws.send(JSON.stringify({code: 400, msg: '找不到老师'}))
                        }
                      }
                    })
                  }else {
                    answer_dao.insert_answer_question(topicId, is_true, stu, subject, answer_time,answer_use_time,lessonId,emoji,answer, function (results) {
                      // console.log(results)
                      if (!results) {
                        conn.get(tea).send({events: 'answer_question', msg: "插入失败"})
                      } else {
                        var tea_ws = conn.get(tea)
                        if (tea_ws) {
                          tea_ws.send(JSON.stringify({
                            events: 'answer_question',
                            data: {
                              student: stu,
                              is_true: is_true,
                              answerId: results.insertId,
                              content: content,
                              topicId: topicId,
                              emoji:emoji
                            }
                          }))
                        } else {
                          ws.send(JSON.stringify({code: 400, msg: '找不到老师'}))
                        }
                      }
                    })

                  }
                })

              })
              // console.log(answer)

            } else {
              ws.send(JSON.stringify({code: 400, msg: '参数错误'}))
              // console.log("参数错误")
            }
            // ws.send
          }
          /**
           * 发送解析
           */
          if (result.events == 'send_description') {
            var tea = result.data.teacher
            if (tea) {
              client.hget(course_students, tea, function (err, reply) {
                if (err) {
                  ws.send(JSON.stringify({code: 500, msg: 'redis错误'}))
                  console.log(err)
                } else if (reply) {
                  students = JSON.parse(reply)
                  var users = new Array()
                  // console.log(students)
                  for (var i = 0; i < students.length; i++) {
                    // console.log(students[i].username)
                    users.push(students[i].username)
                  }
                  broadcast(users, JSON.stringify({events: 'send_description', data: result.data}))
                  ws.send(JSON.stringify({events: 'send_description', msg: "发送解析"}))
                } else {
                  ws.send(JSON.stringify({code: 400, msg: '当前课程已经结束'}))
                }
              })
            } else {
              if (ws) {
                ws.send(JSON.stringify({code: 400, msg: '参数错误'}))
              }
            }
          }
          // console.log(JSON.parse(data))
          /**
           * 获取缺课学生信息
           */
          if (result.events == 'miss_class') {
            var classId = result.data.classId
            var lessonId=result.data.lessonId
            var call_name_time=time=result.data.callNameTime
            var emoji=result.data.emoji
            if (!classId||!lessonId||!call_name_time||!emoji) {
              ws.send(JSON.stringify({code: 400, msg: '参数错误'}))
            } else {
              client.hget(miss_students, classId, function (err, reply) {
                if (err) {
                  ws.send(JSON.stringify({code: 500, msg: 'redis错误'}))
                  console.log(err)
                } else {
                  var miss_class = JSON.parse(reply)
                  var params=new Array()
                  for(var i in miss_class){
                    var each_param=new Array()
                    each_param.push(lessonId,miss_class[i].id)
                    each_param.push(call_name_time)
                    each_param.push(emoji)
                    params.push(each_param)
                  }
                  lesson_dao.miss_class(params,function (results) {
                    console.log(results)
                  ws.send(JSON.stringify({events: 'miss_class', data: {students: miss_class}}))
                  })
                }
              })
            }
          }
          /**
           * 下课
           */
          if (result.events == 'end_class') {
            var tea = result.data.teacher
            var lessonId=result.data.lessonId
            var courseTableId=result.data.courseTableId
            var classId=result.data.classId
            console.log(courseTableId)
            if (tea && lessonId && courseTableId && classId) {
              client.multi([
                  ["hget",course_students,tea],
                  ["hdel",lessons,courseTableId],
                  ["hdel",miss_students,classId],
                  ["hdel",course_students,tea]
              ]).exec(function (err,replies) {
                if (err) {
                  ws.send(JSON.stringify({code: 500, msg: 'redis错误'}))
                  console.log(err)
                } else if (replies) {
                  console.log(replies)
                  students = JSON.parse(replies[0])
                  var users = new Array()
                  if(students){
                  for (var i = 0; i < students.length; i++) {
                    // console.log(students[i].username)
                    users.push(students[i].username)
                  }
                  }
                  console.log(users)
                  course_table_dao.end_class(courseTableId,function (results) {
                    console.log(results)
                    if(ws){
                      ws.send(JSON.stringify({events:'end_class',msg:'下课成功'}))
                    }
                    broadcast(users,JSON.stringify({events:"end_class",msg:'下课了',data:{lessonId:lessonId}}))
                  })
                }

              })

            } else {
              ws.send(JSON.stringify({code: 400, msg: "参数错误"}))
            }
          }
        } catch (e) {
          console.log('error' + e.stack)
        }

        //   conn.set(result.msg,ws)
        //   console.log(result.msg)
        //   conn.get(result.msg,function(err,val){getCourseInfoByTeacher
        //     console.log(val.toString)
        //   })
      })
      }catch (e){
        console("error: "+e.stack)
      }
      ws.on("close", function () {
        var username = socket_user.get(ws)
        socket_user.delete(ws)
        if (username != undefined) {
          conn.delete(username)
        }
        // console.log(username)
        console.log(username + " close")
        // console.log(new Date()+'keys:'+conn.keys())
      })
    })

  },
  broadcast:function(users,msg) {
    for(var user in users){
      var user_socket=conn.get(user)
      if(user_socket!=undefined&&user_socket!=null){
        user_socket.send(msg)
      }
    }
  }

}
/**
 * 广播
 * @param users
 * @param msg
 */
function broadcast(users,msg) {
  for(var i=0; i<users.length; i++){
    var user_socket=conn.get(users[i])
    // console.log(user_socket)
    if(user_socket!=undefined&&user_socket!=null){
      // console.log(users[i])
      user_socket.send(msg)
    }
  }
}
